/**
 * Created with CLion.
 * Description: 
 * User: loong
 * Date: 2025/4/24
 * Time: 22:56
 */

#include "Player.h"

#include "affiliate/Collider.h"
#include "affiliate/Sprite.h"
#include "affiliate/SpriteAnim.h"
#include "core/Scene.h"
#include "raw/Stats.h"
#include "world/Effect.h"

void Player::Init()
{
    Actor::Init();
    max_speed_ = 500.0f;

    sprite_idle_ = SpriteAnim::AddSpriteAnimChild(this, "../assets/sprite/ghost-idle.png", 2.0f);
    sprite_move_ = SpriteAnim::AddSpriteAnimChild(this, "../assets/sprite/ghost-move.png", 2.0f);
    sprite_move_->SetActive(false);

    collider_ = Collider::AddColliderChild(this, sprite_idle_->GetSize() / 2.0f);
    stats_ = Stats::AddStatsChild(this);
    effect_ = Effect::AddEffectChild(nullptr, "../assets/effect/1764.png", glm::vec2(0), 2.0f);
}

void Player::Render()
{
    Actor::Render();
}

void Player::Clean()
{
    Actor::Clean();
}

void Player::HandleEvent(SDL_Event & _event)
{
    Actor::HandleEvent(_event);
}

void Player::Update(float _dt)
{
    Actor::Update(_dt);

    velocity_ *= 0.9f;
    CheckState();
    KeyboardControl();
    Move(_dt);
    SyncCamera();
    CheckIsDead();
}

void Player::KeyboardControl()
{
    auto currentKeyStates = SDL_GetKeyboardState(nullptr);
    if(currentKeyStates[SDL_SCANCODE_W]) {
        velocity_.y = -max_speed_;
    }
    if(currentKeyStates[SDL_SCANCODE_S]) {
        velocity_.y = max_speed_;
    }
    if(currentKeyStates[SDL_SCANCODE_A]) {
        velocity_.x = -max_speed_;
    }
    if(currentKeyStates[SDL_SCANCODE_D]) {
        velocity_.x = max_speed_;
    }
}

void Player::SyncCamera()
{
    game_.GetCurrentScene()->SetCameraPosition(position_ - game_.GetScreenSize() / 2.0f);
}

void Player::CheckState()
{
    sprite_move_->SetFlip(velocity_.x < 0.0f);
    sprite_idle_->SetFlip(velocity_.x < 0.0f);

    bool moving = (glm::length(velocity_) > 0.1f);

    if(moving != is_moving_) {
        is_moving_ = moving;
        ChangeState(moving);
    }
}

void Player::CheckIsDead()
{
    if(!stats_->IsAlive()) {
        game_.GetCurrentScene()->SafeAddChild(effect_);
        effect_->SetPosition(GetPosition());
        SetActive(false);
    }
}

void Player::ChangeState(bool _moving)
{
    sprite_move_->SetActive(_moving);
    sprite_idle_->SetActive(!_moving);

    if(_moving) {
        sprite_move_->SetCurrentFrame(sprite_idle_->CurrentFrame());
        sprite_move_->SetFrameTimer(sprite_idle_->FrameTimer());
    }
    else {
        sprite_idle_->SetCurrentFrame(sprite_move_->CurrentFrame());
        sprite_idle_->SetFrameTimer(sprite_move_->FrameTimer());
    }
}